package com.cn.serverline.lineicp.produce.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.serverline.lineicp.produce.Enum.TeamsGroupEnum;
import com.cn.serverline.lineicp.produce.entity.dto.ContinueDto;
import com.cn.serverline.lineicp.produce.entity.vo.*;
import com.cn.serverline.lineicp.produce.entity.ProduceStartEndEntity;
import com.cn.serverline.lineicp.produce.entity.dto.AddStartTimeDto;
import com.cn.serverline.lineicp.produce.entity.dto.EquipmentTaskDto;
import com.cn.serverline.lineicp.produce.entity.vo.MaterialComponentsVo;
import com.cn.serverline.lineicp.produce.entity.vo.MaterialResourcesVo;
import com.cn.serverline.lineicp.produce.mapper.ProduceStartEndMapper;
import com.cn.serverline.lineicp.workshopPlan.entity.PlanLineAutomatic;
import com.cn.serverline.lineicp.workshopPlan.entity.PlanLineSchedule;
import com.cn.serverline.lineicp.produce.mapper.TaskMapper;
import com.cn.serverline.lineicp.produce.service.TaskService;
import com.cn.serverline.lineicp.workshopPlan.entity.request.ExamineRequest;
import com.cn.serverline.lineicp.workshopPlan.service.IPlanLineAutomaticService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, PlanLineSchedule> implements TaskService {

    @Resource
    private TaskMapper taskMapper;

    @Resource
    private ProduceStartEndMapper produceStartEndMapper;

    @Resource
    private IPlanLineAutomaticService IPlanLineAutomaticService;

    /**
     * 获取部装任务
     *
     * @param equipmentTaskDto
     * @return
     */
    @Override
    public List<EquipmentTaskVo> getEquipment(EquipmentTaskDto equipmentTaskDto) {
        if (equipmentTaskDto.getTaskStartTime() != null){
            equipmentTaskDto.setTask(DateUtil.parse(equipmentTaskDto.getTaskStartTime()));
        }
        return taskMapper.getEquipment(equipmentTaskDto);
    }

    /**
     * 获取总装任务
     *
     * @param equipmentTaskDto
     * @return
     */
    @Override
    public List<AssemblysTaskVo> getAssembly(EquipmentTaskDto equipmentTaskDto) {
        List<AssemblysTaskVo> assemblysTaskVos = new ArrayList<>();
        if (equipmentTaskDto.getTaskStartTime() != null){
            equipmentTaskDto.setTask(DateUtil.parse(equipmentTaskDto.getTaskStartTime()));
        }
        List<AssemblyTaskVo> assemblyTasks = taskMapper.getAssembly(equipmentTaskDto);

        // 使用 Map 进行分组，键是 lotNo，值是对应的 AssemblyTaskVo 列表
        Map<String, List<AssemblyTaskVo>> groupedByLotNo = assemblyTasks.stream()
                .distinct() // 去重
                .collect(Collectors.groupingBy(AssemblyTaskVo::getLotNo));
        // 将分组后的结果转换为 AssemblysTaskVo 列表
        for (Map.Entry<String, List<AssemblyTaskVo>> entry : groupedByLotNo.entrySet()) {
            AssemblysTaskVo assemblysTaskVo = new AssemblysTaskVo();
            assemblysTaskVo.setLotNo(entry.getKey());
            assemblysTaskVo.setProdConfigurationName(entry.getValue().get(0).getProdConfigurationName());
            assemblysTaskVo.setBatchQuantity(entry.getValue().get(0).getBatchQuantity());
            assemblysTaskVo.setProcessName(entry.getValue().stream().map(AssemblyTaskVo::getProcessName).collect(Collectors.toList()));
            List<AssemblysTask> assemblysTaskList = new ArrayList<AssemblysTask>();
            for (AssemblyTaskVo assemblyTaskVo : entry.getValue()) {
                AssemblysTask assemblysTask = new AssemblysTask();
                assemblysTask.setId(assemblyTaskVo.getId());
                assemblysTask.setTaskStartTime(assemblyTaskVo.getTaskStartTime());
                assemblysTask.setTaskEndTime(assemblyTaskVo.getTaskEndTime());
                assemblysTask.setSmallBatchNumber(assemblyTaskVo.getSmallBatchNumber());
                assemblysTask.setPlanQuantity(assemblyTaskVo.getPlanQuantity());
                // 获取编码
                assemblysTask.setPartNumberRange(getCode(assemblyTaskVo.getId()));
                assemblysTask.setStaterNumber(assemblyTaskVo.getStaterNumber());
                assemblysTaskList.add(assemblysTask);
            }
            assemblysTaskVo.setAssemblysTask(assemblysTaskList);
            assemblysTaskVos.add(assemblysTaskVo);
        }

        return assemblysTaskVos;
    }

    /**
     * 获取编码
     *
     * @param id
     * @return
     */
    public String getCode(Long id) {
        try {
            Code code = taskMapper.partNumber(id);
            return code.getPartNumberRange();
        } catch (Exception e) {
            return null;
        }

    }


    /**
     * 获取总装进行中的任务
     *
     * @param equipmentTaskDto
     * @return
     */
    @Override
    public List<AssemblyTaskVo> getAssemblyIn(EquipmentTaskDto equipmentTaskDto) {
        return taskMapper.getAssembly(equipmentTaskDto);
    }

    /**
     * 开工检查（部、总）
     *
     * 根据任务编号决定调用不同的检查方法。
     *
     * @param examineRequest 检查请求对象，其中包含任务编号等信息
     * @return 检查结果列表，根据任务编号返回不同的检查结果
     */
    @Override
    public List<MaterialComponentsVo> CommencementInspectionExamine(ExamineRequest examineRequest) {
        // 根据任务编号决定调用不同的检查方法
        if (examineRequest.getTaskNum().equals("total")) {
            // 如果任务编号为"total"，调用总检查方法
            List<MaterialComponentsVo> totalExamine = taskMapper.CommencementTotalExamine(examineRequest);
            return totalExamine;
        } else if (examineRequest.getTaskNum().equals("division")) {
            // 如果任务编号为"division"，调用分部检查方法
            List<MaterialComponentsVo> divisionExamine = taskMapper.CommencementDivisionExamine(examineRequest);
            return divisionExamine;
        }
        // 如果任务编号不匹配任何预期值，返回null
        return null;
    }

    /**
     * 开工检查（工具、工装、设备）
     *
     * 根据任务编号决定调用不同的检查方法，并设置每个资源的数量为1。
     *
     * @param examineRequest 检查请求对象，其中包含任务编号等信息
     * @return 检查结果列表，根据任务编号返回不同的检查结果
     */
    @Override
    public List<MaterialResourcesVo> CommencementResourcesExamine(ExamineRequest examineRequest) {
        if (examineRequest.getTaskNum().equals("total")) {
            // 如果任务编号为"total"，调用总检查方法
            List<MaterialResourcesVo> totalExamine = taskMapper.CommencementTotalResourcesExamine(examineRequest);
            // 遍历检查结果，将每个资源的数量设置为1
            totalExamine.stream().forEach(materialResourcesVo -> {
                materialResourcesVo.setNumber(1);
            });
            return totalExamine;
        } else if (examineRequest.getTaskNum().equals("division")) {
            // 如果任务编号为"division"，调用分部检查方法
            List<MaterialResourcesVo> divisionExamine = taskMapper.CommencementDivisionResourcesExamine(examineRequest);
            // 遍历检查结果，将每个资源的数量设置为1
            divisionExamine.stream().forEach(materialResourcesVo -> {
                materialResourcesVo.setNumber(1);
            });
            return divisionExamine;
        }
        // 如果任务编号不匹配任何预期值，返回null
        return null;
    }

    /**
     * 添加开始时间
     *
     * 将当前时间作为开始时间记录到数据库中。
     *
     * @param addStartTimeDto 包含需要添加的开始时间信息的DTO对象
     */
    @Override
    public void AddStartTime(AddStartTimeDto addStartTimeDto) {
        ProduceStartEndEntity endEntity = new ProduceStartEndEntity();
        endEntity.setRemark(addStartTimeDto.getRemark());
        endEntity.setAutomaticScheduleId(addStartTimeDto.getAutomaticScheduleId());
        endEntity.setDistinguish(addStartTimeDto.getDistinguish());
        endEntity.setStartTime(new Date()); // 设置当前时间为开始时间
        produceStartEndMapper.insert(endEntity); // 将实体插入数据库
    }

    /**
     * 添加结束时间
     *
     * 根据ID更新记录的结束时间为当前时间。
     *
     * @param id 记录的唯一标识符，用于更新结束时间
     */
    @Override
    public void AddEndTime(Long id) {
        ProduceStartEndEntity endEntity = new ProduceStartEndEntity();
        endEntity.setId(id); // 设置要更新的记录的ID
        endEntity.setEndTime(new Date()); // 设置当前时间为结束时间
        produceStartEndMapper.update(endEntity,
                new LambdaQueryWrapper<ProduceStartEndEntity>().eq(ProduceStartEndEntity::getId, id)); // 更新数据库中的结束时间
    }

    /**
     * 继续任务部装
     * @param continueDto
     */
    @Override
    public void continueTask(ContinueDto continueDto) {
        if(continueDto.getStaterNumber()==2) {
            LambdaQueryWrapper<PlanLineSchedule> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PlanLineSchedule::getStaterNumber, TeamsGroupEnum.TOW.getValue());
            long one = this.count(queryWrapper);
            if (one > 0) {
                throw new SecurityException("当前有任务正在进行，请先结束任务");
            }
        }
        PlanLineSchedule planLineSchedule = new PlanLineSchedule();
        BeanUtils.copyProperties(continueDto, planLineSchedule);
        this.updateById(planLineSchedule);
    }

    /**
     * 继续任务总装
     * @param continueDto
     */
    @Override
    public void continueTasks(ContinueDto continueDto) {
        if(continueDto.getStaterNumber()==2){
            LambdaQueryWrapper<PlanLineAutomatic> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PlanLineAutomatic::getStaterNumber, TeamsGroupEnum.TOW.getValue());
            long one = IPlanLineAutomaticService.count(queryWrapper);
            if (one > 0) {
                throw new SecurityException("当前有任务正在进行，请先结束任务");
            }
        }
        PlanLineAutomatic planLineSchedulec = new PlanLineAutomatic();
        BeanUtils.copyProperties(continueDto, planLineSchedulec);
        IPlanLineAutomaticService.updateById(planLineSchedulec);
    }

}
